﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using WiimoteLib;
using System.Configuration;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.IO;
using System.Configuration.Assemblies;
using WiiMote;
using System.Reflection;
using System.Threading;

namespace WiiMote
{
    public partial class Form1 : Form
    {

        #region Form Loading


        public Form1()
        {
            InitializeComponent();
        }

        NotifyIcon fn;
        Wiimote wm = new Wiimote();
        //string[] settings = File.ReadAllLines("settings.config");
        int padding = 400;


        private void Form1_Load(object sender, EventArgs e)
        {
            b = new Bitmap(pB1.Size.Width, pB1.Size.Height, PixelFormat.Format24bppRgb);
            g = Graphics.FromImage(b);
            Icon resIcon = new Icon(Assembly.GetExecutingAssembly().GetManifestResourceStream("WiiMote.wii.ico"));
            this.Icon = resIcon;
            fn = new NotifyIcon();
            fn.Icon = resIcon;
            fn.Visible = true;
            fn.Text = "WiiMote";
            fn.MouseClick += new MouseEventHandler(fn_MouseClick);
            fn.ContextMenuStrip = contextMenuStrip1;
            try
            {
                wm.Connect();
            }
            catch(Exception ex)
            {
                MessageBox.Show("WiiMote not found. No bluetooth connection." + 
                    Environment.NewLine +
                    Environment.NewLine + 
                    ex.Message);
                Application.Exit();
            }
            wm.SetReportType(InputReport.IRAccel, true);
            wm.WiimoteChanged += wm_WiimoteChanged;
            wm.WiimoteExtensionChanged += wm_WiimoteExtensionChanged;

            if (wm.WiimoteState.ExtensionType == ExtensionType.Nunchuk)
                wm.SetReportType(InputReport.ButtonsExtension, true);
            else
                wm.SetReportType(InputReport.IRAccel, true);

            wm.SetLEDs(15);
        }

        void fn_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            openToolStripMenuItem.PerformClick();
        }

        #endregion

        #region Extension Changed
        private void wm_WiimoteExtensionChanged(object sender, WiimoteExtensionChangedEventArgs args)
        {

            if (wm.WiimoteState.ExtensionType == ExtensionType.Nunchuk)
                wm.SetReportType(InputReport.ButtonsExtension, true);
            else
                wm.SetReportType(InputReport.IRAccel, true);
        }
        #endregion

        #region MouseEvent
        [DllImport("user32.dll")]
        private static extern void mouse_event(uint flags, int x, int y);
        void MouseCommand(uint value)
        {
            mouse_event(value, Cursor.Position.X, Cursor.Position.Y);
        }
        #endregion

        #region WiiMote Action
        void wm_WiimoteChanged(object sender, WiimoteChangedEventArgs args)
        {
            #region Nunchuck
            if (args.WiimoteState.ExtensionType == ExtensionType.Nunchuk)
            {
                #region Joystick
                int speedMultiplier = 10;
                if (args.WiimoteState.NunchukState.AccelState.Values.Y < -0.50
                    || args.WiimoteState.NunchukState.AccelState.Values.X < -0.65
                    || args.WiimoteState.NunchukState.AccelState.Values.X > 0.65
                    )
                {
                    speedMultiplier = 35;
                }
                System.Drawing.Point curPos = Cursor.Position;
                WiimoteLib.PointF nunPos = args.WiimoteState.NunchukState.Joystick;
                int nunx = System.Convert.ToInt32((nunPos.X - 0.01) * speedMultiplier);
                int nuny = System.Convert.ToInt32(nunPos.Y * speedMultiplier * -1);
                Cursor.Position = new System.Drawing.Point(curPos.X + nunx, curPos.Y + nuny);

                #endregion

                #region Left Click
                    bool nunZ = args.WiimoteState.NunchukState.Z;
                if (zPressed == true)
                {
                    if (nunZ == false)
                    {
                        MouseCommand(0x0004); //up
                        zPressed = false;
                    }
                }
                if (nunZ)
                {
                    if (zPressed == false)
                    {
                        zPressed = true;
                        MouseCommand(0x0002); //down
                    }
                }
                #endregion

                #region Right Click
                bool nunC = args.WiimoteState.NunchukState.C;
                if (cPressed == true)
                {
                    if (nunC == false)
                    {
                        MouseCommand(0x0010); //up
                        cPressed = false;
                    }
                }
                if (nunC)
                {
                    if (cPressed == false)
                    {
                        cPressed = true;
                        MouseCommand(0x0008); //down
                    }
                }
                #endregion

            }
            #endregion

            #region Cursor
            #region From IR


            WiimoteLib.PointF pointF = args.WiimoteState.IRState.IRSensors[0].Position;
            Rectangle screenSize = Screen.PrimaryScreen.Bounds;
            int x = screenSize.Width - System.Convert.ToInt32(pointF.X * System.Convert.ToSingle(screenSize.Width + padding)) + padding / 2;
            int y = System.Convert.ToInt32(pointF.Y * System.Convert.ToSingle(screenSize.Height + padding)) - padding / 2;
            if (x < screenSize.Width + 100 && y < screenSize.Height + 100)
            {
                System.Drawing.Point curPoint = new System.Drawing.Point(x, y);
                Cursor.Position = curPoint;
            }

            #endregion

            #region From Tilt Axis

            if (args.WiimoteState.ExtensionType != ExtensionType.Nunchuk)
            {
                if (checkBox2.Checked)
                {
                    int speedMultiplier = 10;
                    System.Drawing.Point curPos = Cursor.Position;
                    float rawx = args.WiimoteState.AccelState.Values.X;
                    float rawy = args.WiimoteState.AccelState.Values.Y * -1;
                    int preppedx = System.Convert.ToInt32((rawx - 0.01) * speedMultiplier);
                    int preppedy = System.Convert.ToInt32(rawy * speedMultiplier * -1);
                    Cursor.Position = new System.Drawing.Point(curPos.X + preppedx, curPos.Y + preppedy);
                }
            }

            #endregion

            #endregion

            #region Button Presses
            WiimoteLib.ButtonState Wiibtn = args.WiimoteState.ButtonState;

            #region Left Click
            if (aPressed == true)
            {
                if (Wiibtn.A == false)
                {
                    MouseCommand(0x0004); //up
                    aPressed = false;
                }
            }
            if (Wiibtn.A == true)
            {
                if (aPressed == false)
                {
                    aPressed = true;
                    MouseCommand(0x0002); //down
                }
            }
            #endregion

            #region Right Click
            if (bPressed == true)
            {
                if (Wiibtn.B == false)
                {
                    MouseCommand(0x0010);
                    bPressed = false;
                }
            }
            if (Wiibtn.B == true)
            {
                if (bPressed == false)
                {
                    bPressed = true;
                    MouseCommand(0x0008);
                }
            }
            #endregion

            #region One Click
            if (onePressed == true)
            {
                if (Wiibtn.One == false)
                {
                    onePressed = false;
                }
            }
            if (Wiibtn.One == true)
            {
                if (onePressed == false)
                {
                    onePressed = true;
                    Process.Start("osk");
                }
            }
            #endregion

            #region Two Click
            if (twoPressed == true)
            {
                if (Wiibtn.Two == false)
                {
                    twoPressed = false;
                }
            }
            if (Wiibtn.Two == true)
            {
                if (twoPressed == false)
                {
                    twoPressed = true;
                    Process.Start("taskmgr");
                }
            }
            #endregion

            #region Home Click
            if (homePressed == true)
            {
                if (Wiibtn.Two == false)
                {
                    twoPressed = false;
                }
            }
            if (Wiibtn.Home == true)
            {
                if (homePressed == false)
                {
                    homePressed = true;
                    Process.Start("explorer.exe", Environment.GetFolderPath(Environment.SpecialFolder.MyComputer));
                }
            }
            #endregion

            #region Other Clicks (SendKeys)
            if (Wiibtn.Down) SendKeys.SendWait("{DOWN}");
            else if (Wiibtn.Left) SendKeys.SendWait("{LEFT}");
            else if (Wiibtn.Up) SendKeys.SendWait("{UP}");
            else if (Wiibtn.Right) SendKeys.SendWait("{RIGHT}");
            else if (Wiibtn.Right) SendKeys.SendWait("{RIGHT}");
            else if (Wiibtn.Minus) SendKeys.SendWait("{PGDN}");
            else if (Wiibtn.Plus) SendKeys.SendWait("{PGUP}");
            #endregion
            #endregion

        }

        #region KeyPress Bools
        bool bPressed = false;
        bool aPressed = false;
        bool onePressed = false;
        bool twoPressed = false;
        bool homePressed = false;
        bool zPressed = false;
        bool cPressed = false;
        #endregion


        #endregion

        #region Timer Tick
        Bitmap b = new Bitmap(1, 1, PixelFormat.Format24bppRgb);
        Graphics g;

        private void timer1_Tick(object sender, EventArgs e)
        {
            progressBar1.Value = System.Convert.ToInt32(wm.WiimoteState.Battery);

            #region Draw IR Point
            WiimoteLib.PointF pf = wm.WiimoteState.IRState.IRSensors[0].Position;

            g.Clear(Color.Black);
            g.DrawEllipse(Pens.Red, pB1.Size.Width - pf.X * pB1.Size.Width, pf.Y * pB1.Size.Height, 10, 4);
            pB1.Image = b;
            #endregion


            /* #region Shake LED
            bool[] ledBool = { false, false, false, false };
            if (Math.Abs(wm.WiimoteState.AccelState.Values.X) > 3)
            {
                if (wm.WiimoteState.LEDState.LED1) ledBool[1] = true;
                else if (wm.WiimoteState.LEDState.LED2) ledBool[2] = true;
                else if (wm.WiimoteState.LEDState.LED3) ledBool[3] = true;
                else ledBool[0] = true;
                wm.SetLEDs(ledBool[0], ledBool[1], ledBool[2], ledBool[3]);
            }
            #endregion */



        }

        #endregion

        #region Tool Strip Buttons
        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            fn.Visible = false;
            Application.Exit();
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.ShowInTaskbar = true;
            this.Show();
        }
        #endregion

        #region Form Closing

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.UserClosing)
            {
                this.Hide();
                e.Cancel = true;
            }
        }

        #endregion

        #region Rumble

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox1.Checked)
            {
                wm.SetRumble(true);
            }
            else
            {
                wm.SetRumble(false);
            }
        }

        #endregion

        #region Trackbar "Sensitivity"

        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            padding = trackBar1.Value;
        }

        #endregion

        #region Config Button

        private void button1_Click(object sender, EventArgs e)
        {
            new Form2().ShowDialog();
        }

        #endregion

        #region LED Race

        private void timer2_Tick(object sender, EventArgs e)
        {


            if (ledState > 8) ledState = 1;
            wm.SetLEDs(ledState);
            ledState = ledState * 2;

          
        }
        int ledState = 1;
        #endregion

    }
}
